﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;

namespace CSharp10.XMLDocumentation
{
    internal class XMLDocTags
    {
        public static void Show()
        {
            /*XElement xe = new XElement("customer",
                new XAttribute("id","123"),
                new XAttribute("name","archived"),
                new XElement("firstname","Jim"),
                new XElement("lastname","Bo"),
                new XElement("creditlimit","500.00"),
                new XComment("OK ,we sneaked this in!")
                );

            XDocument doc = new XDocument(new XDeclaration("1.0","utf-8","yes"),xe);

            doc.Save("customer.xml");

            Console.WriteLine("OK");*/

            /*//XElement xe = new XElement("customer2",
            //    new XAttribute("id","123"),
            //    new XAttribute("status","archived"));
            //xe.Save("customer2.xml");
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            XmlReader reader = XmlReader.Create("customer2.xml", settings);
            reader.MoveToContent();
            //Console.WriteLine(reader["id"]);
            //Console.WriteLine(reader["status"]);
            //Console.WriteLine(reader[0]);
            //Console.WriteLine(reader[1]);
            //Console.WriteLine(reader.AttributeCount);
            //Console.WriteLine(reader["bogus"] == null);

            //reader.MoveToAttribute("id");
            //int id = reader.ReadContentAsInt();
            //Console.WriteLine(id);
            //reader.MoveToAttribute("status");
            //string status = reader.ReadContentAsString();
            //Console.WriteLine(status);
            if (reader.MoveToFirstAttribute())
            {
                do
                {
                    Console.WriteLine(reader.Name +" = "+reader.Value);
                }while (reader.MoveToNextAttribute());
            }

*/

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            //settings.OmitXmlDeclaration = true;
            //settings.ConformanceLevel = ConformanceLevel.Fragment;  // 2个作用：1 可以不写声明内容，2 允许有多个根节点
            using XmlWriter writer = XmlWriter.Create("foo.xml",settings);
            //writer.WriteStartElement("customer");
            //writer.WriteElementString("firstname", "Jim");
            //writer.WriteElementString("lastname", "Bo");
            //writer.WriteEndElement();
            //writer.WriteStartElement("wja");
            //writer.WriteElementString("name", "wja");
            //writer.WriteEndElement();
            //writer.WriteStartElement("birthdate");
            //writer.WriteValue(DateTime.Now);
            //writer.WriteEndElement();
            ////writer.WriteStartElement("shengri");
            //writer.WriteElementString("shengri", DateTime.Now.ToString());

            // 写入特性
            //writer.WriteStartElement("customer");
            //writer.WriteAttributeString("id", "123");
            //writer.WriteAttributeString("status", "on");
            //writer.WriteStartAttribute("age");
            //writer.WriteValue(23);
            //writer.WriteEndAttribute();
            //writer.WriteElementString("firstname", "Jim");
            //writer.WriteElementString("lastname", "Bo");
            //writer.WriteEndElement();
            //writer.WriteComment("这个是注释内容");

            // 写命名空间和前缀
            //writer.WriteStartElement("o", "customer", "http://oreilly.com");
            //writer.WriteElementString("o", "firstname", "http://oreilly.com", "Jim");
            //writer.WriteElementString("o", "lastname", "http://oreilly.com", "Bo");
            //writer.WriteEndElement();
            //Console.WriteLine("OK");

        }

        public static void Show2()
        {
            /*  XmlWriterSettings settings  =new XmlWriterSettings();
            settings.Indent = true;
          using XmlWriter writer = XmlWriter.Create("contacts.xml", settings);
            var cts = new Contracts();
            var c1 = new Customer();
            c1.ID = 1;
            c1.FirstName = "wang";
            c1.LastName = "jingan";
            cts.Customers.Add(c1);
            var c2 = new Customer();
            c2.ID = 2;
            c2.FirstName = "lin";
            c2.LastName = "xinru";
            cts.Customers.Add(c2);
            var c3 = new Customer();
            c3.ID = 3;
            c3.FirstName = "tang";
            c3.LastName = "yan";
            cts.Customers.Add(c3);

            var c4 = new Customer();
            c4.FirstName = "enenen";
            c4.LastName = "asfasf";
            cts.Customers.Add(c4);


            var s1 = new Supplier();
            s1.Name = "Test";
            cts.Suppliers.Add(s1);
            var s2 = new Supplier();
            s2.Name = "Test2";
            cts.Suppliers.Add(s2);
            var s3 = new Supplier();
            s3.Name = "enen";
            cts.Suppliers.Add(s3);

            writer.WriteStartElement("contacts");
            cts.WriteXml(writer);
            writer.WriteEndElement();*/


            //var settings = new XmlReaderSettings();
            //settings.IgnoreWhitespace = true;
            //settings.IgnoreComments = true;
            //settings.IgnoreProcessingInstructions = true;
            //using XmlReader reader = XmlReader.Create("contacts.xml", settings);
            //reader.MoveToContent();
            //var cts = new Contracts();
            //cts.ReadXml(reader);

            //Console.ReadLine();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            using XmlWriter writer = XmlWriter.Create("logfile.xml");
            writer.WriteStartElement("log");
            for(int i =0; i < 1000000; i++)
            {
                XElement e = new XElement("logentry",
                    new XAttribute("id", i),
                    new XElement("date", DateTime.Today.AddDays(-1)),
                    new XElement("source", "test"));
                e.WriteTo(writer);
            }
            writer.WriteEndElement();

            Console.WriteLine("ok");

        }
    }

    /// <summary>
    /// Customer 类
    /// </summary>
    public class Customer
    {
        /// <summary>
        /// XmlName 
        /// </summary>
        public const string XmlName = "customer";
        /// <summary>
        /// id 
        /// </summary>
        public int? ID;
        /// <summary>
        /// firstname lastname
        /// </summary>
        public string FirstName, LastName;
        /// <summary>
        /// 构造函数
        /// </summary>
        public Customer(){ }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="r"></param>
        public Customer(XmlReader r)
        {
            ReadXml(r);
        }
        /// <summary>
        /// 读取xml
        /// </summary>
        /// <param name="r"></param>
        public void ReadXml(XmlReader r)
        {
            //if(r.MoveToAttribute("id"))ID = r.ReadContentAsInt();
            //r.ReadStartElement();
            //FirstName = r.ReadElementContentAsString();
            //LastName = r.ReadElementContentAsString();
            //r.ReadEndElement();
            XElement x = (XElement)XNode.ReadFrom(r);
            ID = (int?)x.Attribute("id");
            FirstName = (string)x.Element("firstname")!;
            LastName = (string)x.Element("lastname")!;
        }
        /// <summary>
        /// 写入xml
        /// </summary>
        /// <param name="w"></param>
        public void WriteXml(XmlWriter w)
        {
            if(ID.HasValue) w.WriteAttributeString("id","",ID.ToString());
            w.WriteElementString("firstname", FirstName);
            w.WriteElementString("lastname",LastName);
        }
    }

    public class Supplier
    {
        public const string XmlName = "supplier";
        public string Name;
        public Supplier() { }
        public Supplier(XmlReader r)
        {
            ReadXml(r);
        }

        public void ReadXml(XmlReader r)
        {
            r.ReadStartElement();
            Name = r.ReadElementContentAsString("name", "");
            r.ReadEndElement();
        }
        public void WriteXml(XmlWriter w) => w.WriteElementString("name", Name);
    }

    public class Contracts
    {
        public IList<Customer> Customers = new List<Customer>();
        public IList<Supplier> Suppliers = new List<Supplier>();

        /// <summary>
        /// 读取xml
        /// </summary>
        /// <param name="r"></param>
        /// <exception cref="XmlException"></exception>
        public void ReadXml(XmlReader r)
        {
            bool isEmpty = r.IsEmptyElement;
            r.ReadStartElement();
            if( isEmpty )  return;
            while (r.NodeType == XmlNodeType.Element)
            {
                if (r.Name == Customer.XmlName) Customers.Add(new Customer(r));
                else if(r.Name == Supplier.XmlName) Suppliers.Add(new Supplier(r));
                else throw new XmlException("Unexpected node:"+r.Name);
            }
            r.ReadEndElement();
        }

        /// <summary>
        /// 写入xml
        /// </summary>
        /// <param name="w"></param>
        public void WriteXml(XmlWriter w)
        {
            foreach(Customer c in Customers)
            {
                w.WriteStartElement(Customer.XmlName);
                c.WriteXml(w);
                w.WriteEndElement();
            }
            foreach(Supplier supp in Suppliers)
            {
                w.WriteStartElement(Supplier.XmlName);
                supp.WriteXml(w);
                w.WriteEndElement();
            }
        }


    }
}
